package com.chenfan.infra.aspect;

import com.chenfan.ccp.utils.TraceIdUtil;
import com.chenfan.infra.client.PrivilegeUserServer;
import com.chenfan.infra.context.TenantContextHolder;
import com.chenfan.infra.entity.STenantRes;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author: tangwei
 * @Date: 2022/4/27 15:49
 * @Description:
 */
@Aspect
@Component
@Slf4j
public class SingleJobTenantAspect {

    @Autowired
    private PrivilegeUserServer privilegeUserServer;

    @Pointcut("@annotation(com.chenfan.infra.annotation.JobTenant)")
    public void pointcut() {
    }

    @Around("pointcut()")
    @SneakyThrows
    public void execute(ProceedingJoinPoint point) {
        List<STenantRes> list = Optional.ofNullable(privilegeUserServer.getAllTenantList()).map(x -> x.getObj()).orElse(Collections.emptyList());

        for (int i = 0; i < list.size(); i++) {
            Long tenantId = list.get(i).getTenantId();
            TenantContextHolder.setTenantId(tenantId);
            log.info("=== 租户[ID：[{}]]执行定时任务 ===", tenantId);
            TraceIdUtil.generateTraceId();
            point.proceed();
            TenantContextHolder.clear();
            TraceIdUtil.clearTrace();
        }
    }

    @AfterThrowing(value = "pointcut()", throwing = "ex")
    @SneakyThrows
    public void executeException(Throwable ex) {
        log.error("=== 定时任务执行发生异常 ===", ex);
        TenantContextHolder.clear();
    }
}